﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Fantom.Expression
{
    public static class FormulaBuilder
    {

        #region 内置的栈结构，用于性能测试，结果发现自己实现的并没有想象的那么高效
        // 参数栈（待优化为限长数组）。
        private static Stack<int> _paraStack = new Stack<int>();
        private const int STACK_SIZE = 16;
        private static int[] _paraArr = new int[STACK_SIZE];
        private static int _stkTop = 0;

        // 压栈。
        private static void StackPush(int num)
        {
            _paraArr[_stkTop++] = num;
        }

        // 出栈。
        private static int StackPop()
        {
            return _paraArr[--_stkTop];
        }

        // 栈是否为空。
        private static bool StackIsEmpty()
        {
            return _stkTop == 0;
        }
        #endregion

        #region 语素提取

        /// <summary>
        /// 从数字开始解析。
        /// </summary>
        private static MetaNode StartFromNumber(string exp, int index, int length, out int pos)
        {
            char ch;

            int p = 0; // 小数点计数。
            int lp = 0; // 上一次是否为小数点。

            pos = index;

            while (pos < length)
            {
                ch = exp[pos]; // 获得当前字符值。

                if (ch <= '9' && ch >= '0')
                {
                    pos++; lp = 0;
                }

                else if (ch == '.')
                {
                    pos++; p++; lp = 1;
                }
                else
                {
                    break;
                }

            }

            var mt = new MetaNode()
            {
                MetaNodes = null,
                KeyWord = MetaKeyWordType.None,
                Type = MetaNodeType.ValueNum
            };

            if (p == 0) // 无小数点的连续数串。
            {
                mt.Value = exp.Substring(index, pos - index);
            }
            else if (p == 1 && lp == 0) // 存在小数点，小数点位置与数量均合法时。
            {
                mt.Value = exp.Substring(index, pos - index);
            }
            else // 存在多个小数点、或小数点位置不合法时。
            {
                mt.Value = exp.Substring(index, pos - index);
                mt.Type = MetaNodeType.Error;
            }
            return mt;
        }

        /// <summary>
        /// 从字母开始解析。
        /// </summary>
        private static MetaNode StartFromAlpha(string exp, int index, int length, out int pos)
        {
            char ch;

            bool sys = true; // 系统函数的可能性。

            pos = index + 1;

            while (pos < length)
            {
                ch = exp[pos]; // 获得当前字符值。

                if (char.IsNumber(ch))
                {
                    pos++; sys = false;
                }

                else if (char.IsLetter(ch))
                {
                    pos++;
                }
                else if (ch == '_')
                {
                    pos++; sys = false;
                }
                else
                {
                    break;
                }

            }

            var mt = new MetaNode() { };

            // 当检测到不可能为系统函数时。
            if (sys == false || pos - index > 5)
            {
                mt.KeyWord = MetaKeyWordType.custom;
                mt.Type = MetaNodeType.Function;
                mt.Value = exp.Substring(index, pos - index);
            }
            else // 当函数为纯字符且长度在5以内时。
            {
                int len = pos - index;
                if (len == 1 && char.ToLower(exp[index]) == 'e')
                {
                    mt.Type = MetaNodeType.ValueConst;
                    mt.KeyWord = MetaKeyWordType.E;
                    mt.Value = "E";
                }
                else if (len == 2 && char.ToLower(exp[index]) == 'p' && char.ToLower(exp[index + 1]) == 'i')
                {
                    mt.Type = MetaNodeType.ValueConst;
                    mt.KeyWord = MetaKeyWordType.PI;
                    mt.Value = "PI";
                }
                else
                {
                    mt.Type = MetaNodeType.Function;
                    mt.KeyWord = MetaKeyWordType.Unknown;
                    mt.Value = exp.Substring(index, pos - index);
                }

            }
            return mt;
        }

        private static MetaNode StartFromSystemConstSign(string exp, int index, int length, out int pos)
        {
            char ch;

            pos = index + 1;

            while (pos < length)
            {
                ch = exp[pos]; // 获得当前字符值。

                if (char.IsNumber(ch))
                {
                    pos++;
                }

                else if (char.IsLetter(ch))
                {
                    pos++;
                }
                else if (ch == '_')
                {
                    pos++;
                }
                else
                {
                    break;
                }

            }

            var mt = new MetaNode() { };

            var substr = exp.Substring(index, pos - index);

            mt.Type = MetaNodeType.ValueConst;
            mt.KeyWord = MetaKeyWordType.SysConst;

            mt.Value = substr;
            mt.Text = "#" + substr;

            return mt;
        }

        /// <summary>
        /// 解析操作符。
        /// </summary>
        private static MetaNode StartFromOperator(string exp, int index, int length, out int pos)
        {
            var ch = exp[index];
            var mt = new MetaNode();
            mt.Type = MetaNodeType.Operator;
            if (ch == '+')
            {
                mt.Value = "+";
                mt.Type = MetaNodeType.Operator;
                mt.KeyWord = MetaKeyWordType.Add;
            }
            else if (ch == '-')
            {
                mt.Value = "-";
                mt.Type = MetaNodeType.Operator;
                mt.KeyWord = MetaKeyWordType.Sub;
            }
            else if (ch == '*')
            {
                mt.Value = "*";
                mt.Type = MetaNodeType.OperatorBinary;
                mt.KeyWord = MetaKeyWordType.Mul;
            }
            else if (ch == '/')
            {
                mt.Value = "/";
                mt.Type = MetaNodeType.OperatorBinary;
                mt.KeyWord = MetaKeyWordType.Div;
            }
            else if (ch == '^')
            {
                mt.Value = "^";
                mt.Type = MetaNodeType.OperatorBinary;
                mt.KeyWord = MetaKeyWordType.Pow;
            }
            else if (ch == '%')
            {
                mt.Value = "%";
                mt.Type = MetaNodeType.OperatorBinary;
                mt.KeyWord = MetaKeyWordType.Mod;
            }
            else
            {
                throw new Exception("符号解析错误。");
            }
            pos = index + 1;
            return mt;

        }

        /// <summary>
        /// 从其他字符开始解析。
        /// </summary>
        private static MetaNode StartFromOtherChar(string exp, int index, int length, out int pos)
        {
            char ch = exp[index];

            if (ch == '.')
            {
                return StartFromNumber(exp, index, length, out pos);
            }

            else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '%')
            {
                return StartFromOperator(exp, index, length, out pos);
            }
            else if (ch == '(')
            {
                var mt = new MetaNode();
                mt.Value = "(";
                mt.Type = MetaNodeType.Empty;
                mt.KeyWord = MetaKeyWordType.StartOfSpace;
                pos = index + 1;
                return mt;
            }
            else if (ch == ')')
            {
                var mt = new MetaNode();
                mt.Value = ")";
                mt.Type = MetaNodeType.Empty;
                mt.KeyWord = MetaKeyWordType.EndOfSpace;
                pos = index + 1;
                return mt;
            }
            else if (ch == ' ')
            {
                pos = index + 1;
                return null;
            }
            else if (ch == '$')
            {
                var mt = new MetaNode();
                mt.Value = "$";
                mt.Type = MetaNodeType.ValueVar;
                pos = index + 1;
                return mt;
            }
            else if (ch == ',')
            {
                var mt = new MetaNode();
                mt.Value = ",";
                mt.Type = MetaNodeType.Empty;
                mt.KeyWord = MetaKeyWordType.SplitOfSpace;
                pos = index + 1;
                return mt;
            }
            else if (ch == '#')
            {
                return StartFromSystemConstSign(exp, index + 1, length, out pos);
            }
            else
            {
                var mt = new MetaNode();
                mt.Value = ch.ToString();
                mt.Type = MetaNodeType.Error;
                pos = index + 1;
                return mt;
            }

            pos = index + 1;
            return null;
        }

        /// <summary>
        /// 获得当前字符串中的最前一位元素。
        /// </summary>
        private static MetaNode GetMetaNode(string exp, int index, int length, out int pos)
        {
            var ch = exp[index];
            if (char.IsNumber(ch))
            {
                return StartFromNumber(exp, index, length, out pos);
            }
            else if (char.IsLetter(ch))
            {
                return StartFromAlpha(exp, index, length, out pos);
            }
            else
            {
                return StartFromOtherChar(exp, index, length, out pos);
            }
            return null;
        }

        /// <summary>
        /// 获得当前表达式组。
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        public static List<MetaNode> CreateExpressionMetaGroup(string exp)
        {
            int pos = 0;
            int len = exp.Length;
            MetaNode mt = null;
            var list = new List<MetaNode>();
            while (pos < len)
            {
                mt = GetMetaNode(exp, pos, len, out pos);
                if (mt != null)
                    list.Add(mt);
            }
            return list;
        }


        #endregion

        #region 检错与补全


        /// <summary>
        /// 经过多次测试与调整得到的元素解析的硬编码版本。
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="functionDic"></param>
        /// <param name="errPos"></param>
        public static void CheckExpressionMataGroupSynax
        (List<MetaNode> nodes, FunctionCatalog functionDic,SystemConstCatalog systemConstDic, out int errPos)
        {
            _stkTop = 0;

            MetaNode node, last;
            int len = nodes.Count;
            errPos = -1;

            if (nodes.Count == 0)
            {
                errPos = -2;
                return;
            }

            node = nodes[0];

            if (node.Type == MetaNodeType.Error)
            {
                errPos = 0;
                return;
            }

            if (node.Type == MetaNodeType.Operator)
            {
                node.Type = MetaNodeType.OperatorSingle;
            }
            else if (node.Type == MetaNodeType.OperatorBinary)
            {
                node.Type = MetaNodeType.Error; errPos = 0; return;
            }
            else if (node.KeyWord == MetaKeyWordType.EndOfSpace ||
                node.KeyWord == MetaKeyWordType.SplitOfSpace)
            {
                node.Type = MetaNodeType.Error; errPos = 0; return;
            }
            else if (node.Type.HasFlag(MetaNodeType.Function))
            {
                if (!functionDic.ContainsKey(node.Value))
                {
                    node.Type = MetaNodeType.Error; errPos = 0; return;
                }
                else
                {
                    node.Type = unchecked(MetaNodeType.FunctionPara0 + functionDic[node.Value].ParameterCount);
                }
            }
            else if(node.Type == MetaNodeType.ValueConst)
            {
                if(node.KeyWord == MetaKeyWordType.SysConst && !systemConstDic.ContainsKey(node.Value))
                {
                    node.Type = MetaNodeType.Error; errPos = 0; return;
                }
            }
            else if (node.Type == MetaNodeType.Empty)
            {
                // 解析开始。
                if (node.KeyWord == MetaKeyWordType.StartOfSpace)
                {
                    _paraArr[_stkTop++] = 1;
                    //_paraStack.Push(1);
                }

                // 解析开始。
                else if (node.KeyWord == MetaKeyWordType.SplitOfSpace)
                {
                    node.Type = MetaNodeType.Error; errPos = 0; return;
                }

                // 解析结束。
                else if (node.KeyWord == MetaKeyWordType.EndOfSpace)
                {
                    node.Type = MetaNodeType.Error; errPos = 0; return;
                }
            }


            for (int i = 1; i < len; i++)
            {
                node = nodes[i];
                if (node.Type == MetaNodeType.Error)
                {
                    errPos = i; return;
                }


                last = nodes[i - 1];

                if (node.Type.HasFlag(MetaNodeType.Value))
                {
                    if (last.Type.HasFlag(MetaNodeType.Value) ||
                        last.KeyWord == MetaKeyWordType.EndOfSpace ||
                        last.Type.HasFlag(MetaNodeType.Function))
                    {
                        node.Type = MetaNodeType.Error; errPos = i; return;
                    }
                    else if (node.Type == MetaNodeType.ValueConst)
                    {
                        if (node.KeyWord == MetaKeyWordType.SysConst && !systemConstDic.ContainsKey(node.Value))
                        {
                            node.Type = MetaNodeType.Error; errPos = i; return;
                        }
                    }
                }

                else if (node.Type.HasFlag(MetaNodeType.Operator))
                {
                    // 待定操作符类型。
                    if (node.Type == MetaNodeType.Operator)
                    {
                        if (last.Type.HasFlag(MetaNodeType.Operator) ||
                            last.KeyWord == MetaKeyWordType.StartOfSpace ||
                            last.KeyWord == MetaKeyWordType.SplitOfSpace ||
                            last.Type.HasFlag(MetaNodeType.Function))
                        {
                            node.Type = MetaNodeType.OperatorSingle;
                        }

                        else
                        {
                            node.Type = MetaNodeType.OperatorBinary;
                        }
                    }

                    else if (node.Type == MetaNodeType.OperatorBinary)
                    {
                        if (last.Type.HasFlag(MetaNodeType.Operator) ||
                            last.KeyWord == MetaKeyWordType.StartOfSpace ||
                            last.KeyWord == MetaKeyWordType.SplitOfSpace ||
                            last.Type.HasFlag(MetaNodeType.Function))
                        {
                            node.Type = MetaNodeType.Error; errPos = i; return;
                        }
                    }
                    // 如果为单目运算符。
                    else
                    {
                        if (last.Type.HasFlag(MetaNodeType.Value) ||
                        last.KeyWord == MetaKeyWordType.EndOfSpace ||
                        last.Type.HasFlag(MetaNodeType.Function))
                        {
                            node.Type = MetaNodeType.Error; errPos = i; return;
                        }
                    }

                }

                else if (node.Type.HasFlag(MetaNodeType.Function))
                {
                    if (last.Type.HasFlag(MetaNodeType.Value) ||
                        last.KeyWord == MetaKeyWordType.EndOfSpace ||
                        !functionDic.ContainsKey(node.Value))
                    {
                        node.Type = MetaNodeType.Error; errPos = i;
                        return;
                    }
                    else
                    {
                        node.Type = unchecked(MetaNodeType.FunctionPara0 + functionDic[node.Value].ParameterCount);
                    }
                }

                else if (node.Type == MetaNodeType.Empty)
                {
                    // 解析开始。
                    if (node.KeyWord == MetaKeyWordType.StartOfSpace)
                    {
                        if (!last.Type.HasFlag(MetaNodeType.Function) &&
                            !last.Type.HasFlag(MetaNodeType.Operator) &&
                            !(last.KeyWord == MetaKeyWordType.StartOfSpace) &&
                            !(last.KeyWord == MetaKeyWordType.SplitOfSpace))
                        {
                            node.Type = MetaNodeType.Error; errPos = i; return;
                        }
                        else if (last.Type.HasFlag(MetaNodeType.Function))
                        {

                            int pc = unchecked(last.Type - MetaNodeType.FunctionPara0);
                            if (pc > 6)
                            {
                                last.Type = MetaNodeType.Error; errPos = i - 1;
                                return;
                            }
                            else if (pc >= 1)
                            {
                                _paraArr[_stkTop++] = pc;
                            }
                            else if (pc == 0)
                            {
                                _paraArr[_stkTop++] = -1;
                            }
                            else
                            {
                                last.Type = MetaNodeType.Error; errPos = i - 1; return;
                            }

                        }
                        else
                        {
                            _paraArr[_stkTop++] = 1;
                        }
                    }

                    // 解析开始。
                    else if (node.KeyWord == MetaKeyWordType.SplitOfSpace)
                    {
                        if (last.Type.HasFlag(MetaNodeType.Function) ||
                            last.Type.HasFlag(MetaNodeType.Operator) ||
                            last.KeyWord == MetaKeyWordType.SplitOfSpace ||
                            last.KeyWord == MetaKeyWordType.StartOfSpace ||
                            _stkTop == 0)
                        {
                            node.Type = MetaNodeType.Error; errPos = i;
                            return;
                        }
                        else
                        {
                            if (_stkTop == 0)
                            {
                                node.Type = MetaNodeType.Error; errPos = i;
                                return;
                            }
                            else
                            {
                                _paraArr[_stkTop - 1]--;
                            }

                        }

                    }

                    // 解析结束。
                    else if (node.KeyWord == MetaKeyWordType.EndOfSpace)
                    {
                        if (last.Type.HasFlag(MetaNodeType.Function) ||
                            last.Type.HasFlag(MetaNodeType.Operator) ||
                            last.KeyWord == MetaKeyWordType.SplitOfSpace)
                        {
                            node.Type = MetaNodeType.Error; errPos = i;
                            return;
                        }
                        else
                        {
                            if (_stkTop == 0) // 栈为空时无法出栈。
                            {
                                node.Type = MetaNodeType.Error; errPos = i;
                                return;
                            }
                            else
                            {
                                int top = _paraArr[--_stkTop]; // 栈不为空时，出栈
                                if (top == -1) // 如果为0参数时
                                {
                                    if (last.KeyWord != MetaKeyWordType.StartOfSpace)
                                    {
                                        node.Type = MetaNodeType.Error; errPos = i;
                                        return;
                                    }

                                }
                                if (top == 1)
                                {
                                    if (last.KeyWord == MetaKeyWordType.StartOfSpace)
                                    {
                                        node.Type = MetaNodeType.Error; errPos = i;
                                        return;
                                    }

                                }
                                else
                                {
                                    node.Type = MetaNodeType.Error; errPos = i;
                                    return;
                                }

                            }


                        }


                    }
                }

            }
            if (_stkTop != 0 ||
                nodes[len - 1].Type.HasFlag(MetaNodeType.Function) ||
                nodes[len - 1].Type.HasFlag(MetaNodeType.Operator))
                errPos = len - 1;
        }

        /// <summary>
        /// 在命令行中显示输出表达式。
        /// </summary>
        internal static void ShowExpressionMetaGroup(List<MetaNode> list, int errPos)
        {
            int len = list.Count;
            for (int i = 0; i < len; i++)
            {
                var node = list[i];
                if (i % 2 == 0)
                    Console.ForegroundColor = ConsoleColor.Yellow;
                else
                    Console.ForegroundColor = ConsoleColor.Green;
                if (node.Type == MetaNodeType.Error || i == errPos)
                    Console.BackgroundColor = ConsoleColor.Red;
                Console.Write(node.Value);
                if (node.Type == MetaNodeType.Error)
                    Console.ResetColor();
                if (!node.Type.HasFlag(MetaNodeType.Function))
                    Console.Write(" ");
            }

            Console.ResetColor();
            Console.WriteLine();
        }

        #endregion

        #region 树的构造
        // 是否为第一级运算符。
        private static bool IsAddOrSub(MetaNode node)
        {
            return node.Type == MetaNodeType.OperatorBinary &&
                    (node.KeyWord == MetaKeyWordType.Add ||
                    node.KeyWord == MetaKeyWordType.Add);
        }

        // 是否为第二级运算符。
        private static bool IsMulOrDivOrMod(MetaNode node)
        {
            return (node.KeyWord == MetaKeyWordType.Mul ||
                    node.KeyWord == MetaKeyWordType.Div || node.KeyWord == MetaKeyWordType.Mod);
        }

        // 是否为乘方。
        private static bool IsPower(MetaNode node)
        {
            return node.KeyWord == MetaKeyWordType.Pow;
        }




        // 是否树结构层级更高。
        private static bool IsHigher(MetaNode nodeA, MetaNode nodeB)
        {
            if (nodeB.KeyWord == MetaKeyWordType.SplitOfSpace)
            {
                return nodeA.Type.HasFlag(MetaNodeType.Function);
            }

            else if (nodeB.KeyWord == MetaKeyWordType.EndOfSpace)
            {
                return nodeA.KeyWord == MetaKeyWordType.StartOfSpace ||
                    nodeA.Type.HasFlag(MetaNodeType.Function);
            }
            else
            {
                if (nodeB.KeyWord == MetaKeyWordType.Pow ||
                    nodeA.KeyWord == MetaKeyWordType.Add ||
                    nodeA.KeyWord == MetaKeyWordType.Sub ||
                    nodeA.Type.HasFlag(MetaNodeType.Empty) ||
                    nodeA.Type.HasFlag(MetaNodeType.Function))

                    return true;

                else
                    return false;
            }

        }


        /// <summary>
        /// 回退到邻近等级的节点。
        /// </summary>
        /// <param name="node"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static MetaNode BackToEqualLevel(MetaNode node, MetaNode newnode)
        {
            node = node.Parent; // node 起点为叶节点。
            while (node != null)
            {
                if (IsHigher(node, newnode)) return node;
                node = node.Parent; // node 起点为叶节点。
            }
            return newnode;
        }

        /// <summary>
        /// 创建表达式树。
        /// </summary>
        /// <param name="list">合法的表达式元素序列。</param>
        /// <returns>带头结点的表达式树的根节点。</returns>
        public static MetaNode CreateExpressionTree(List<MetaNode> list)
        {
            var root = new MetaNode() { Type = MetaNodeType.Empty };
            var last = root;
            var node = last;
            int i = 0, len = list.Count;

            while (i < len)
            {
                last = node;
                node = list[i];
                if (node.Type.HasFlag(MetaNodeType.Value))
                {
                    node.Parent = last;
                    last.MetaNodes[last.Top++] = node;
                }
                else if (node.Type == MetaNodeType.OperatorBinary)
                {
                    last = BackToEqualLevel(last, node);
                    var child = last.MetaNodes[last.Top - 1];
                    node.MetaNodes[node.Top++] = child;
                    child.Parent = node;
                    node.Parent = last;
                    last.MetaNodes[last.Top - 1] = node;
                }
                else if (node.Type.HasFlag(MetaNodeType.Function))
                {
                    node.Parent = last;
                    last.MetaNodes[last.Top++] = node;
                    i++;
                }
                else if (node.Type == MetaNodeType.OperatorSingle)
                {
                    node.Parent = last;
                    last.MetaNodes[last.Top++] = node;
                }
                else if (node.KeyWord == MetaKeyWordType.StartOfSpace)
                {
                    node.Parent = last;
                    last.MetaNodes[last.Top++] = node;
                }
                else if (node.KeyWord == MetaKeyWordType.EndOfSpace)
                {
                    node = BackToEqualLevel(last, node);
                }
                else if (node.KeyWord == MetaKeyWordType.SplitOfSpace)
                {
                    node = BackToEqualLevel(last, node);
                }
                i++;
            }

            return root;
        }
        #endregion

        #region 树的计算
        /// <summary>
        /// 计算表达式。
        /// </summary>
        /// <param name="node">一个已被构造成树或子树的合法节点。</param>
        /// <param name="functionDic">函数字典，用于检索函数。</param>
        /// <param name="varValue">变量值的当前值。</param>
        /// <returns>一个双精度浮点类型的结果值。</returns>
        public static double CalcExpressionTree(MetaNode node, FunctionCatalog functionDic, SystemConstCatalog systemConstDic, double varValue = 0d)
        {
            if (node == null) return 0d;

            else if (node.Type == MetaNodeType.Empty)
            {
                return CalcExpressionTree(node.MetaNodes[0], functionDic, systemConstDic, varValue);
            }

            else if (node.Type.HasFlag(MetaNodeType.Function))
            {
                var arr = new double[6];
                for (int i = 0; i < node.Top; i++)
                {
                    arr[i] = CalcExpressionTree(node.MetaNodes[i], functionDic, systemConstDic, varValue);
                }
                return functionDic[node.Value].Func(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
            }

            else if (node.Type.HasFlag(MetaNodeType.Value))
            {
                if (node.Type == MetaNodeType.ValueNum)
                    return double.Parse(node.Value);
                else if (node.Type == MetaNodeType.ValueVar)
                    return varValue;
                else if (node.Type == MetaNodeType.ValueConst)
                {
                    if (node.KeyWord == MetaKeyWordType.PI)
                        return Math.PI;
                    else if (node.KeyWord == MetaKeyWordType.PI)
                        return Math.E;
                    else if (node.KeyWord == MetaKeyWordType.SysConst)
                        return systemConstDic.GetRecord(node.Value);
                }
            }

            else if (node.Type == MetaNodeType.OperatorBinary)
            {
                var v1 = CalcExpressionTree(node.MetaNodes[0], functionDic, systemConstDic, varValue);
                var v2 = CalcExpressionTree(node.MetaNodes[1], functionDic, systemConstDic, varValue);
                if (node.KeyWord == MetaKeyWordType.Add)
                    return v1 + v2;
                else if (node.KeyWord == MetaKeyWordType.Sub)
                    return v1 - v2;
                else if (node.KeyWord == MetaKeyWordType.Mul)
                    return v1 * v2;
                else if (node.KeyWord == MetaKeyWordType.Div)
                    return v1 / v2;
                else if (node.KeyWord == MetaKeyWordType.Pow)
                    return Math.Pow(v1, v2);
                else if (node.KeyWord == MetaKeyWordType.Mod)
                    return v1 % v2;
            }

            else if (node.Type == MetaNodeType.OperatorSingle)
            {
                return (node.KeyWord == MetaKeyWordType.Sub ? -1 : 1) *
                    CalcExpressionTree(node.MetaNodes[0], functionDic, systemConstDic, varValue);
            }

            return 0d;
        }

        #endregion

        #region 树的输出
        /// <summary>
        /// 按照一定格式在命令行输出节点。
        /// </summary>
        private static void WriteWithSpace(string str, int depth)
        {
            for (int i = 0; i < depth; i++)
                Console.Write("   ");
            Console.BackgroundColor = (ConsoleColor)((depth + 7) % 16);
            Console.ForegroundColor = (ConsoleColor)((depth + 13) % 16);
            Console.Write("{0,-4}", str);
            Console.ResetColor();
            Console.WriteLine();
        }


        /// <summary>
        /// 递归遍历地输出树的结构。
        /// </summary>
        /// <param name="node">根节点值。</param>
        /// <param name="depth">树的默认深度。</param>
        internal static void ShowExpressionTree(MetaNode node, int depth = 0)
        {
            if (node == null)
                return;
            else if (node.Type == MetaNodeType.Empty)
            {
                WriteWithSpace("()", depth);

                ShowExpressionTree(node.MetaNodes[0], depth + 1);

                // WriteWithSpace(")", depth);
            }
            else if (node.Type.HasFlag(MetaNodeType.Function))
            {
                WriteWithSpace(node.Value + "()", depth);

                for (int i = 0; i < node.Top; i++)
                {
                    if (i != 0)
                        WriteWithSpace(", ", depth + 1);
                    ShowExpressionTree(node.MetaNodes[i], depth + 2);

                }
                // WriteWithSpace(")", depth);
            }
            else if (node.Type.HasFlag(MetaNodeType.Value))
            {
                WriteWithSpace(node.Value, depth);
            }
            else if (node.Type == MetaNodeType.OperatorBinary)
            {
                ShowExpressionTree(node.MetaNodes[0], depth + 1);
                WriteWithSpace(node.Value, depth);
                ShowExpressionTree(node.MetaNodes[1], depth + 1);
            }
            else if (node.Type == MetaNodeType.OperatorSingle)
            {
                WriteWithSpace(node.Value, depth);
                ShowExpressionTree(node.MetaNodes[0], depth + 1);
            }


        }
        #endregion


        #region 综合功能

        /// <summary>
        /// 计算并得出该表达式的所有分析结果。
        /// </summary>
        /// <param name="exp">表达式原字符串。</param>
        /// <param name="varValue">变量值。</param>
        /// <param name="functionDic">函数清单，此处可以填 null，使用默认函数清单。</param>
        /// <param name="metaNodes">元节点列表。</param>
        /// <param name="root">表达式树根节点。</param>
        /// <param name="result">表达式的值。</param>
        /// <param name="errPos">表达式出错位置。</param>
        public static void CalculateExpression
            (string exp, double varValue, FunctionCatalog functionDic, SystemConstCatalog systemConstDic, out List<MetaNode> metaNodes, out MetaNode root, out double result, out int errPos)
        {
            if (functionDic == null)
                functionDic = FunctionCatalog.DefaultFunctions;
            if (systemConstDic == null)
                systemConstDic = SystemConstCatalog.DefaultSystemConsts;

            root = null;
            result = 0d;

            // 划分字段。
            metaNodes = CreateExpressionMetaGroup(exp);

            // 附加语义并检查语法。
            CheckExpressionMataGroupSynax(metaNodes, functionDic,systemConstDic, out errPos);

            if (errPos == -1)
            {
                // 构造表达式树。
                root = CreateExpressionTree(metaNodes);

                // 计算表达式树。
                result = CalcExpressionTree(root, functionDic, systemConstDic, varValue);
            }

        }

        public static string GetAdjustedFormula(List<MetaNode> metaNodes)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < metaNodes.Count; i++)
            {
                if (i != 0 && !metaNodes[i - 1].Type.HasFlag(MetaNodeType.Function))
                {
                    sb.Append(" ");
                }

                sb.Append(metaNodes[i].Text);
            }
            return sb.ToString();

        }

        #endregion


    }
}
